package com.dbgs.cpic.jfw.utils;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * 
 * AES加密解密
 * @author dai
 *
 */
public class AESCBC {


	private final String keyGen = "AES";


	private final String cipherStr = "AES/CBC/PKCS5Padding";//"AES/CBC/PKCS5Padding" AES/CBC/PKCS7Padding
	private String key = "6b6132686a6732653136386873366734"; //AES固定格式为128/192/256 bits.即：16/24/32bytes。DES固定格式为128bits，即8bytes。
	private String iv = "63766231327876627835766234786166";

	public AESCBC(String key, String iv) {
		super();
		if (key !=null && key.length() > 0 ) {
			this.key = key;
		}
		if (iv !=null && iv.length() > 0 ) {
			this.iv = iv;
		}

	}



	public String encrypt(String text) throws Exception{


		Key keySpec = new SecretKeySpec(hexToByte(key), keyGen);    //两个参数，第一个为私钥字节数组， 第二个为加密方式 AES或者DES
		IvParameterSpec ivSpec = new IvParameterSpec(hexToByte(iv));
		Cipher cipher = Cipher.getInstance(cipherStr); //实例化加密类，参数为加密方式，要写全

		
		cipher.init(Cipher.ENCRYPT_MODE,  keySpec, ivSpec);           //初始化，此方法可以采用三种方式，按服务器要求来添加。（1）无第三个参数（2）第三个参数为SecureRandom random = new SecureRandom();中random对象，随机数。(AES不可采用这种方法)（3）采用此代码中的IVParameterSpec

		//cipher.init(Cipher.ENCRYPT_MODE, keySpec);

		//SecureRandom random = new SecureRandom();

		//cipher.init(Cipher.ENCRYPT_MODE, keySpec, random);

		

		byte [] b = cipher.doFinal(text.getBytes());                  //加密操作,返回加密后的字节数组，然后需要编码。主要编解码方式有Base64, HEX, UUE, 7bit等等。此处看服务器需要什么编码方式

		String ret = byteToHex(b);                                       //Base64、HEX等编解码

		return ret;
	}
	
	
	
	public  String decrypt(String text) throws Exception{



		byte [] byte1 = hexToByte(text);         //先用Base64解码



		Key keySpec = new SecretKeySpec(hexToByte(key), keyGen);    //两个参数，第一个为私钥字节数组， 第二个为加密方式 AES或者DES
		IvParameterSpec ivSpec = new IvParameterSpec(hexToByte(iv));
		Cipher cipher = Cipher.getInstance(cipherStr); //实例化加密类，参数为加密方式，要写全

		
		cipher.init(cipher.DECRYPT_MODE, keySpec, ivSpec);               //与加密时不同MODE:Cipher.DECRYPT_MODE

		byte [] ret = cipher.doFinal(byte1);

		return new String(ret, "UTF-8");

		}


	
	
	public static void main(String[] args) throws Exception {
	
		long time1 = System.currentTimeMillis();
		AESCBC aseAes128 =  new AESCBC(null,null);
//		for (int i = 0; i < 100; i++) {
//			String encC = (aseAes128.encrypt("1234"));
//			String desc  = aseAes128.decrypt(encC);
//			System.out.println(encC+"--"+desc);
//		}
		System.out.println(aseAes128.encrypt("13012345671"));

		System.out.println(aseAes128.decrypt("dc9bc8dd01e032cb60276b78c9132741"));
//		String key = "6b6132686a6732653136386873366734";
//		System.out.println(new String(hexToByte(key)));
	}





	/**
	 * hex转byte数组
	 * @param hex
	 * @return
	 */
	public static byte[] hexToByte(String hex){
		int m = 0, n = 0;
		int byteLen = hex.length() / 2; // 每两个字符描述一个字节
		byte[] ret = new byte[byteLen];
		for (int i = 0; i < byteLen; i++) {
			m = i * 2 + 1;
			n = m + 1;
			int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
			ret[i] = Byte.valueOf((byte)intVal);
		}
		return ret;
	}

	/**
	 * byte数组转hex
	 * @param bytes
	 * @return
	 */
	public static String byteToHex(byte[] bytes){
		String strHex = "";
		StringBuilder sb = new StringBuilder("");
		for (int n = 0; n < bytes.length; n++) {
			strHex = Integer.toHexString(bytes[n] & 0xFF);
			sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
		}
		return sb.toString().trim();
	}
	
	


		 
	
}
